
/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2016原作者。
 *
 *根据Apache许可证2.0版（“许可证”）获得许可；
 *除非符合许可证，否则不得使用此文件。
 *您可以在以下地址获取许可证副本：
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，软件
 *根据许可证分发的内容是按“原样”分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限和
 *许可证下的限制。
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.lang.Nullable;

/**
 * Strategy interface used by a {@link ConfigurableBeanFactory},
 * representing a target scope to hold bean instances in.
 * This allows for extending the BeanFactory's standard scopes
 * {@link ConfigurableBeanFactory#SCOPE_SINGLETON "singleton"} and
 * {@link ConfigurableBeanFactory#SCOPE_PROTOTYPE "prototype"}
 * with custom further scopes, registered for a
 * {@link ConfigurableBeanFactory#registerScope(String, Scope) specific key}.
 *
 * <p>{@link org.springframework.context.ApplicationContext} implementations
 * such as a {@link org.springframework.web.context.WebApplicationContext}
 * may register additional standard scopes specific to their environment,
 * e.g. {@link org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST "request"}
 * and {@link org.springframework.web.context.WebApplicationContext#SCOPE_SESSION "session"},
 * based on this Scope SPI.
 *
 * <p>Even if its primary use is for extended scopes in a web environment,
 * this SPI is completely generic: It provides the ability to get and put
 * objects from any underlying storage mechanism, such as an HTTP session
 * or a custom conversation mechanism. The name passed into this class's
 * {@code get} and {@code remove} methods will identify the
 * target object in the current scope.
 *
 * <p>{@code Scope} implementations are expected to be thread-safe.
 * One {@code Scope} instance can be used with multiple bean factories
 * at the same time, if desired (unless it explicitly wants to be aware of
 * the containing BeanFactory), with any number of threads accessing
 * the {@code Scope} concurrently from any number of factories.
 *
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @since 2.0
 * @see ConfigurableBeanFactory#registerScope
 * @see CustomScopeConfigurer
 * @see org.springframework.aop.scope.ScopedProxyFactoryBean
 * @see org.springframework.web.context.request.RequestScope
 * @see org.springframework.web.context.request.SessionScope
 */
/**
 *｛@link ConfigurationBeanFactory｝使用的策略接口，
 *表示用于保存bean实例的目标范围。
 *这允许扩展BeanFactory的标准范围
 *｛@link ConfigurationBeanFactory#SCOPE_SINGLETON“SINGLETON”｝和
 *｛@link ConfigurationBeanFactory#SCOPE_PROTOTYPE“原型”｝
 *具有自定义的其他作用域，已注册
 *｛@link ConfigurationBeanFactory#registerScope（String，Scope）特定键｝。
 *
 *＜p＞｛@link org.springframework.context.ApplicationContext｝实现
 *例如｛@link org.springframework.web.context.WebApplicationContext｝
 *可以注册特定于其环境的附加标准范围，
 *例如｛@link org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST“REQUEST”｝
 *和{@link org.springframework.web.context.WebApplicationContext#SCOPE_SESSION“会话”}，
 *基于该范围SPI。
 *
 *＜p＞即使其主要用途是用于web环境中的扩展范围，
 *这个SPI是完全通用的：它提供了获取和放置
 *来自任何底层存储机制（如HTTP会话）的对象
 *或自定义对话机制。传递到此类的
 *｛@code get｝和｛@ccode remove｝方法将标识
 *当前范围中的目标对象。
 *
 *＜p＞｛@code Scope｝实现应该是线程安全的。
 *一个｛@code Scope｝实例可以用于多个bean工厂
 *同时，如果需要（除非它明确希望了解
 *包含BeanFactory），任意数量的线程访问
 *｛@code Scope｝从任意数量的工厂并发生成。
 *
 *@作者Juergen Hoeller
 *@作者Rob Harrop
 *@自2.0起
 *@参见可配置的BeanFactory#registerScope
 *@参见CustomScopeConfig
 *@参见org.springframework.aop.scope.ScopedProxyFactoryBean
 *@参见org.springframework.web.context.request.RequestScope
 *@参见org.springframework.web.context.request.SessionScope
 */
public interface Scope {

	/**
	 * Return the object with the given name from the underlying scope,
	 * {@link org.springframework.beans.factory.ObjectFactory#getObject() creating it}
	 * if not found in the underlying storage mechanism.
	 * <p>This is the central operation of a Scope, and the only operation
	 * that is absolutely required.
	 * @param name the name of the object to retrieve
	 * @param objectFactory the {@link ObjectFactory} to use to create the scoped
	 * object if it is not present in the underlying storage mechanism
	 * @return the desired object (never {@code null})
	 * @throws IllegalStateException if the underlying scope is not currently active
	 */
	/**
	 *从基础作用域返回具有给定名称的对象，
	 *｛@link org.springframework.beans.factory.ObjectFactory#getObject（）正在创建它｝
	 *如果在底层存储机制中找不到。
	 *＜p＞这是作用域的中心操作，也是唯一的操作
	 *这是绝对需要的。
	 *@param name要检索的对象的名称
	 *@param objectFactory要用于创建作用域的｛@link objectFactory｝
	 *对象，如果它不在基础存储机制中
	 *@返回所需对象（从不｛@code null｝）
	 *如果基础作用域当前不活动，@throws IllegalStateException
	 */
	Object get(String name, ObjectFactory<?> objectFactory);

	/**
	 * Remove the object with the given {@code name} from the underlying scope.
	 * <p>Returns {@code null} if no object was found; otherwise
	 * returns the removed {@code Object}.
	 * <p>Note that an implementation should also remove a registered destruction
	 * callback for the specified object, if any. It does, however, <i>not</i>
	 * need to <i>execute</i> a registered destruction callback in this case,
	 * since the object will be destroyed by the caller (if appropriate).
	 * <p><b>Note: This is an optional operation.</b> Implementations may throw
	 * {@link UnsupportedOperationException} if they do not support explicitly
	 * removing an object.
	 * @param name the name of the object to remove
	 * @return the removed object, or {@code null} if no object was present
	 * @throws IllegalStateException if the underlying scope is not currently active
	 * @see #registerDestructionCallback
	 */
	/**
	 *从基础作用域中删除具有给定｛@code name｝的对象。
	 *＜p＞如果找不到对象，则返回｛@code null｝；否则
	 *返回删除的｛@code Object｝。
	 *＜p＞请注意，实现还应删除已注册的销毁
	 *指定对象的回调（如果有）。然而，<i>不是</i>
	 *在这种情况下，需要＜i＞执行＜/i＞注册的销毁回调，
	 *因为对象将被调用者销毁（如果合适）。
	 *＜p＞＜b＞注意：这是一个可选操作</b> 实施可能会引发
	 *｛@link UnsupportedOperationException｝，如果它们不明确支持
	 *移除对象。
	 *@param name要删除的对象的名称
	 *@返回删除的对象，如果没有对象，则返回｛@code null｝
	 *如果基础作用域当前不活动，@throws IllegalStateException
	 *@参见#registerDestructionCallback
	 */
	@Nullable
	Object remove(String name);

	/**
	 * Register a callback to be executed on destruction of the specified
	 * object in the scope (or at destruction of the entire scope, if the
	 * scope does not destroy individual objects but rather only terminates
	 * in its entirety).
	 * <p><b>Note: This is an optional operation.</b> This method will only
	 * be called for scoped beans with actual destruction configuration
	 * (DisposableBean, destroy-method, DestructionAwareBeanPostProcessor).
	 * Implementations should do their best to execute a given callback
	 * at the appropriate time. If such a callback is not supported by the
	 * underlying runtime environment at all, the callback <i>must be
	 * ignored and a corresponding warning should be logged</i>.
	 * <p>Note that 'destruction' refers to automatic destruction of
	 * the object as part of the scope's own lifecycle, not to the individual
	 * scoped object having been explicitly removed by the application.
	 * If a scoped object gets removed via this facade's {@link #remove(String)}
	 * method, any registered destruction callback should be removed as well,
	 * assuming that the removed object will be reused or manually destroyed.
	 * @param name the name of the object to execute the destruction callback for
	 * @param callback the destruction callback to be executed.
	 * Note that the passed-in Runnable will never throw an exception,
	 * so it can safely be executed without an enclosing try-catch block.
	 * Furthermore, the Runnable will usually be serializable, provided
	 * that its target object is serializable as well.
	 * @throws IllegalStateException if the underlying scope is not currently active
	 * @see org.springframework.beans.factory.DisposableBean
	 * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getDestroyMethodName()
	 * @see DestructionAwareBeanPostProcessor
	 */
	/**
	 *注册要在销毁指定的
	 *对象（或整个范围的破坏，如果
	 *作用域不销毁单个对象，而只终止
	 *整体）。
	 *＜p＞＜b＞注意：这是一个可选操作</b> 此方法将仅
	 *为具有实际销毁配置的作用域bean调用
	 *（DisposableBean，destroy方法，DestructionAwareBeanPostProcessor）。
	 *实现应尽力执行给定的回调
	 *在适当的时间。如果
	 *底层运行时环境，回调＜i＞必须是
	 *忽略，并应记录相应的警告</i>。
	 *＜p＞注意，“销毁”是指自动销毁
	 *对象是范围自身生命周期的一部分，而不是个人
	 *应用程序已显式删除作用域对象。
	 *如果通过此facade的｛@link#remove（String）｝删除了作用域对象
	 *方法，也应删除任何已注册的销毁回调，
	 *假设移除的对象将被重用或手动销毁。
	 *@param name要为其执行销毁回调的对象的名称
	 *@param callback要执行的销毁回调。
	 *注意，传入的Runnable永远不会抛出异常，
	 *因此它可以在没有封闭的try-catch块的情况下安全地执行。
	 *此外，如果
	 *它的目标对象也是可序列化的。
	 *如果基础作用域当前不活动，@throws IllegalStateException
	 *@参见org.springframework.beans.factory.DisposableBean
	 *@see org.springframework.beans.factory.support.AbstractBeanDefinition#getDestroyMethodName（）
	 *@参见DestructionAwareBeanPostProcessor
	 */
	void registerDestructionCallback(String name, Runnable callback);

	/**
	 * Resolve the contextual object for the given key, if any.
	 * E.g. the HttpServletRequest object for key "request".
	 * @param key the contextual key
	 * @return the corresponding object, or {@code null} if none found
	 * @throws IllegalStateException if the underlying scope is not currently active
	 */
	/**
	 *解析给定键的上下文对象（如果有）。
	 *例如，键“request”的HttpServletRequest对象。
	 *@param key上下文键
	 *@返回相应的对象，如果未找到，则返回｛@code null｝
	 *如果基础作用域当前不活动，@throws IllegalStateException
	 */
	@Nullable
	Object resolveContextualObject(String key);

	/**
	 * Return the <em>conversation ID</em> for the current underlying scope, if any.
	 * <p>The exact meaning of the conversation ID depends on the underlying
	 * storage mechanism. In the case of session-scoped objects, the
	 * conversation ID would typically be equal to (or derived from) the
	 * {@link jakarta.servlet.http.HttpSession#getId() session ID}; in the
	 * case of a custom conversation that sits within the overall session,
	 * the specific ID for the current conversation would be appropriate.
	 * <p><b>Note: This is an optional operation.</b> It is perfectly valid to
	 * return {@code null} in an implementation of this method if the
	 * underlying storage mechanism has no obvious candidate for such an ID.
	 * @return the conversation ID, or {@code null} if there is no
	 * conversation ID for the current scope
	 * @throws IllegalStateException if the underlying scope is not currently active
	 */
	/**
	 *返回当前基础作用域的<em>会话ID</em>（如果有）。
	 *＜p＞会话ID的确切含义取决于
	 *存储机制。对于会话范围的对象
	 *会话ID通常等于（或源自）
	 *｛@link jakarta.servlet.http.HttpSession#getId（）会话ID｝；在
	 *在整个会话内的定制会话的情况下，
	 *当前会话的特定ID将是适当的。
	 *＜p＞＜b＞注意：这是一个可选操作</b> 这对
	 *如果
	 *底层存储机制没有明显的候选ID。
	 *@返回对话ID，如果没有，则返回｛@code null｝
	 *当前作用域的会话ID
	 *如果基础作用域当前不活动，@throws IllegalStateException
	 */
	@Nullable
	String getConversationId();

}
